package org.zju.demo.controller;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RestController;
import org.zju.demo.model.*;
import org.zju.demo.model.Product;
import org.zju.demo.model.request.*;
import org.zju.demo.model.response.*;
import org.zju.demo.service.intf.*;
import org.zju.demo.utils.Constant;
import org.zju.demo.utils.Log;

import java.sql.Timestamp;
import java.util.ArrayList;
import java.util.List;

/**
 * Created by admin on 2015/8/25.
 */
@RestController
public class ShoppingAPI {

    @Autowired
    private CategoryInfoIntf categoryService;
    @Autowired
    private ProductInfoIntf productService;
    @Autowired
    private ProductCategoryIntf productCategoryService;
    @Autowired
    private OrderInfoIntf orderService;
    @Autowired
    private OrderUserIntf orderUserService;
    @Autowired
    private OrderProductIntf orderProductService;
    @Autowired
    private UserProductIntf userProductService;
    @Autowired
    private UserIntf userService;

    @RequestMapping(value = "/api/shopping/getHot", method = RequestMethod.POST)
    public ResponseHotJson queryHot(@RequestBody RequestJson requestJson) {
        ResponseHotJson response = new ResponseHotJson();
        response.setCommand_id(Constant.COMMAND_QUERYHOT);
        if (requestJson.getCommand_id() != Constant.COMMAND_QUERYHOT) {
            response.setResult(Constant.UNKNOWN_REASON);
            response.setMessage(Constant.MSG_UNKNOWN_REASON);
            return response;
        }
        List<Product> list = productService.getAllProduct();
        if(list == null) {
            response.setResult(Constant.NO_PRODUCT);
            response.setMessage(Constant.MSG_NO_PRODUCT);
            return response;
        }
        response.setResult(Constant.SUCCESS);
        response.setMessage(Constant.MSG_SUCCESS);
        List<ResponseProduct> products = new ArrayList<ResponseProduct>();
        for(Product product: list) {
            ResponseProduct product1 = new ResponseProduct();
            product1.setProduct_id(product.getProductId());
            product1.setProduct_name(product.getProductName());
            product1.setProduct_price(product.getPrice());
            //设置图片地址
            product1.setProduct_image(product.getImageAddress());
            products.add(product1);
        }
        response.setProducts(products);
        return response;
    }

    @RequestMapping(value = "/api/shopping/getGoods", method = RequestMethod.POST)
    public ResponseCategoryJson queryCategory(@RequestBody RequestGetCategoryJson requestJson) {
        ResponseCategoryJson response = new ResponseCategoryJson();
        response.setCommand_id(Constant.COMMAND_QUERYGOODS);

        if (requestJson.getCommand_id() != Constant.COMMAND_QUERYGOODS) {
            response.setResult(Constant.UNKNOWN_REASON);
            response.setMessage(Constant.MSG_UNKNOWN_REASON);
            return response;
        }
        Log.println(requestJson.toString());
        // find all the products belong to goods_category
        List<ProductCategory> list = productCategoryService.findByCategoryId(requestJson.getGoods_category());
        if (categoryService.findById(requestJson.getGoods_category()) == null) {
            response.setResult(Constant.UNKNOWN_CATEGORY);
            response.setMessage(Constant.MSG_UNKNOWN_CATEGORY);
            return response;
        }

        response.setResult(Constant.SUCCESS);
        response.setMessage(Constant.MSG_SUCCESS);
        // get the detail about each product
        List<ResponseProduct> responseProducts = new ArrayList<ResponseProduct>();
        for (ProductCategory productCategory: list) {
            Product product = productService.findByProductId(productCategory.getProductId());
            // set basic information
            ResponseProduct responseProduct = new ResponseProduct();
            responseProduct.setProduct_id(product.getProductId());
            responseProduct.setProduct_name(product.getProductName());
            responseProduct.setProduct_price(product.getPrice());
            responseProducts.add(responseProduct);
        }
        response.setGoods_list(responseProducts);

        // leave the recommend as empty
        return response;
    }

    @RequestMapping(value = "/api/shopping/getSpecificProduct", method = RequestMethod.POST)
    public ResponseProductDetailJson getSpecificProduct(@RequestBody RequestProductDetailJson productDetailJson) {
        ResponseProductDetailJson responseJson = new ResponseProductDetailJson();
        responseJson.setCommand_id(Constant.COMMAND_QUERYPRODUCT);
        if (productDetailJson.getCommand_id() != Constant.COMMAND_QUERYPRODUCT) {
            responseJson.setResult(Constant.UNKNOWN_REASON);
            responseJson.setMessage(Constant.MSG_UNKNOWN_REASON);
            return responseJson;
        }

        Log.println(productDetailJson.toString());
        // find all the information
        Product product = productService.findByProductId(productDetailJson.getProduct_id());
        if(product == null) {
            responseJson.setResult(Constant.UNKNOWN_PRODUCT);
            responseJson.setMessage(Constant.MSG_UNKNOWN_PRODUCT);
            return responseJson;
        }
        responseJson.setResult(Constant.SUCCESS);
        responseJson.setMessage(Constant.MSG_SUCCESS);

        responseJson.setProduct_amount(product.getAmount());
        responseJson.setProduct_name(product.getProductName());
        responseJson.setProduct_company(product.getProductName());
        responseJson.setProduct_popular_degree(product.getPopular());
        responseJson.setProduct_price(product.getPrice());
        responseJson.setProduct_saled_number(product.getSaledNumber());
        //deal with image
        responseJson.setProduct_image(product.getImageAddress());
        // retrieve all the comments related to the product
        List<UserProduct> userProducts = userProductService.findByProductId(product.getProductId());
        List<Comment> comments = new ArrayList<Comment>();
        for (UserProduct obj: userProducts) {
            Comment comment = new Comment();
            comment.setComment(obj.getComment());
            comment.setUser(Integer.toString(obj.getUserId()));
            comment.setScore(obj.getScore());
            comments.add(comment);
        }
        responseJson.setProduct_comments(comments);

        return responseJson;
    }

    @RequestMapping(value = "/api/shopping/buyProducts", method = RequestMethod.POST)
    public ResponseOrderJson buyProducts(@RequestBody RequestBuyJson requestBuyJson) {
        ResponseOrderJson responseOrderJson = new ResponseOrderJson();
        responseOrderJson.setCommand_id(Constant.COMMAND_BUY);
        User user = userService.findByUsername(requestBuyJson.getUsername());

        if (requestBuyJson.getCommand_id() != Constant.COMMAND_BUY || user == null) {
            responseOrderJson.setResult(Constant.UNKNOWN_REASON);
            responseOrderJson.setMessage(Constant.MSG_UNKNOWN_REASON);
            return responseOrderJson;
        }
        Log.println(requestBuyJson.toString());

        Order order = new Order();

        float total = 0;
        List<OrderProduct> orderProducts = new ArrayList<OrderProduct>();
        List<Product> products = new ArrayList<Product>();

        for (RequestProduct requestProduct: requestBuyJson.getProducts()) {
            // first query product price
            Product product = productService.findByProductId(requestProduct.getProduct_id());
            // ensure that there is enough products
            if (product == null || product.getAmount() < requestProduct.getNumber()) {
                responseOrderJson.setResult(Constant.UNKNOWN_REASON);
                responseOrderJson.setMessage(Constant.MSG_UNKNOWN_REASON);
                return responseOrderJson;
            }
            product.setAmount(product.getAmount() - requestProduct.getNumber());
            products.add(product);

            OrderProduct orderProduct = new OrderProduct();
            orderProduct.setProductId(product.getProductId());
            orderProduct.setAmount(requestProduct.getNumber());
            orderProduct.setPrice(product.getPrice());
            orderProducts.add(orderProduct);

            total += product.getPrice() * requestProduct.getNumber();
        }
        // persist order
        order.setAddress(requestBuyJson.getAddress());
        order.setCustomName(requestBuyJson.getUsername());
        order.setFinished(Constant.ORDER_UNFINISHED);
        order.setStatus(Constant.ORDER_STATUS_START);
        order.setTime(new Timestamp(System.currentTimeMillis()));
        order.setTotalPrice(total);
        order.setCustomName(requestBuyJson.getUsername());
        int status = orderService.addOrder(order);
        if (status == 1) {
            responseOrderJson.setResult(Constant.UNKNOWN_REASON);
            responseOrderJson.setMessage(Constant.MSG_UNKNOWN_REASON);
            return responseOrderJson;
        }

        for (OrderProduct orderProduct : orderProducts) {
            orderProduct.setOrderId(order.getOrderId());
            orderProductService.addItem(orderProduct);
        }
        // update the product
        for (Product product: products) {
            productService.updateProduct(product);
        }
        // add item to OrderUser;
        OrderUser orderUser = new OrderUser();
        orderUser.setOrderId(order.getOrderId());
        orderUser.setUserId(user.getUserId());
        orderUserService.save(orderUser);
        // then fill the response code
        responseOrderJson.setResult(Constant.SUCCESS);
        responseOrderJson.setMessage(Constant.MSG_SUCCESS);
        responseOrderJson.setOrder_id(order.getOrderId());
        responseOrderJson.setOrder_money(order.getTotalPrice());
        return responseOrderJson;
    }

    @RequestMapping(value = "/api/order/queryAll", method = RequestMethod.POST)
    public ResponseQueryOrderJson queryAll(@RequestBody RequestGetOrderListJson request) {
        ResponseQueryOrderJson response = new ResponseQueryOrderJson();
        response.setCommand_id(Constant.COMMAND_QUERYORDER);
        if (request.getCommand_id()!= Constant.COMMAND_QUERYORDER) {
            response.setResult(Constant.UNKNOWN_REASON);
            response.setMessage(Constant.MSG_UNKNOWN_REASON);
            return response;
        }
        //first find userid
        User user = userService.findByUsername(request.getUsername());
        if(user == null) {
            response.setResult(Constant.UNKNOWN_REASON);
            response.setMessage(Constant.MSG_UNKNOWN_REASON);
            return response;
        }
        //retrieve all the order related to user;
        List<OrderUser> orderUsers = orderUserService.findByUserId(user.getUserId());
        List<Order> orders = new ArrayList<Order>();

        List<ResponseOrder> responseOrders = new ArrayList<ResponseOrder>();

        for (OrderUser orderUser: orderUsers) {
            // for some order
            Order order = orderService.findById(orderUser.getOrderId());
            List<OrderProduct> orderProducts = orderProductService.findByOrderId(orderUser.getOrderId());
            // check
            if (order == null || orderProducts == null) {
                response.setResult(Constant.UNKNOWN_REASON);
                response.setMessage(Constant.MSG_UNKNOWN_REASON);
                return response;
            }
            List<Item> responseProducts = new ArrayList<Item>();
            // Get all the product in the order
            for (OrderProduct orderProduct: orderProducts) {
                Product product = productService.findByProductId(orderProduct.getProductId());
                Item item = new Item();
                // check
                if (product == null) {
                    response.setResult(Constant.UNKNOWN_REASON);
                    response.setMessage(Constant.MSG_UNKNOWN_REASON);
                    return response;
                }
                item.setProduct_name(product.getProductName());
                item.setProduct_amount(orderProduct.getAmount());
                item.setProduct_price(orderProduct.getPrice());
                responseProducts.add(item);
            }
            // add to responseOrder
            ResponseOrder responseOrder = new ResponseOrder();
            responseOrder.setProducts(responseProducts);
            responseOrder.setAddress(order.getAddress());
            if (order.getFinished() == Constant.ORDER_FINISHED) {
                responseOrder.setFinished(1);
            } else {
                responseOrder.setFinished(0);
            }
            responseOrder.setTime(order.getTime().toString());
            responseOrder.setOrder_id(order.getOrderId());

            responseOrders.add(responseOrder);
        }
        response.setOrders(responseOrders);
        response.setResult(Constant.SUCCESS);
        response.setMessage(Constant.MSG_SUCCESS);
        return response;
    }

    @RequestMapping(value = "/api/order/getDeliveryStatus", method = RequestMethod.POST)
    public ResponseDeliveryJson getDeliverStatusJson(@RequestBody ReqeustGetDeliverStatusJson request) {
        ResponseDeliveryJson response = new ResponseDeliveryJson();
        response.setCommand_id(Constant.COMMAND_QUEYRDELIVERY);
        if (request.getCommand_id() != response.getCommand_id()) {
            response.setResult(Constant.UNKNOWN_REASON);
            response.setMessage(Constant.MSG_UNKNOWN_REASON);
            return response;
        }

        return response;
    }

    @RequestMapping(value = "/api/order/setOrderStatus", method = RequestMethod.POST)
    public BasicResponseJson setOrderStatus(@RequestBody ReqeustSetOrderStatusJson request) {
        System.out.println("setOrderStatus " + request.getCommand_id() + " " + request.getUsername() + " " + request.getOrder_status());
        BasicResponseJson response = new BasicResponseJson();
        response.setCommand_id(Constant.COMMAND_SETORDER);
        if (request.getCommand_id() != Constant.COMMAND_SETORDER) {
            response.setResult(Constant.UNKNOWN_REASON);
            response.setMessage(Constant.MSG_UNKNOWN_REASON);
            return response;
        }
        Order order = orderService.findById(request.getOrder_id());
        if(order == null) {
            response.setResult(Constant.UNKNOWN_ORDER);
            response.setMessage(Constant.MSG_UNKNOWN_ORDER);
            return response;
        }

        if( request.getUsername().equals("admin")) {
//            if (order.getStatus().equals(Constant.ORDER_STATUS_START) ){
//                if (!request.getOrder_status().equals(Constant.ORDER_STATUS_BEFORE_PRODUCE) ){
//                    response.setMessage(Constant.MSG_WRONG_ORDER_STATUS);
//                    response.setResult(Constant.WRONG_ORDER_STATUS);
//                    return response;
//                }
//            } else if (order.getStatus().equals(Constant.ORDER_STATUS_BEFORE_PRODUCE)) {
//                if (!request.getOrder_status().equals( Constant.ORDER_STATUS_AFTER_PRODUCE) ){
//                    response.setMessage(Constant.MSG_WRONG_ORDER_STATUS);
//                    response.setResult(Constant.WRONG_ORDER_STATUS);
//                    return response;
//                }
//            } else {
//                response.setMessage(Constant.MSG_WRONG_ORDER_STATUS);
//                response.setResult(Constant.WRONG_ORDER_STATUS);
//                return response;
//            }
            order.setStatus(request.getOrder_status());
            orderService.update(order);

            response.setResult(Constant.SUCCESS);
            response.setMessage(Constant.MSG_SUCCESS);
            return response;
        } else {
//            if (!order.getStatus().equals(Constant.ORDER_STATUS_AFTER_PRODUCE)) {
//                response.setMessage(Constant.MSG_WRONG_ORDER_STATUS);
//                response.setResult(Constant.WRONG_ORDER_STATUS);
//                return response;
//            } else if (!request.getOrder_status().equals(Constant.ORDER_STATUS_FINISH) ){
//                response.setMessage(Constant.MSG_WRONG_ORDER_STATUS);
//                response.setResult(Constant.WRONG_ORDER_STATUS);
//                return response;
//            }
            order.setStatus(request.getOrder_status());
            orderService.update(order);

            response.setResult(Constant.SUCCESS);
            response.setMessage(Constant.MSG_SUCCESS);
            return response;
        }
    }
    // return orders that do not produce
    @RequestMapping(value = "/api/order/produce", method = RequestMethod.POST)
    public ResponseQueryOrderJson produce(@RequestBody BasicRequestJson json){
        System.out.println("ShoppingAPI produce" + json.toString());
        ResponseQueryOrderJson response = new ResponseQueryOrderJson();
        response.setCommand_id(Constant.COMMAND_PRODUCE);
        if (json.getCommand_id() != Constant.COMMAND_PRODUCE) {
            response.setResult(Constant.UNKNOWN_REASON);
            response.setMessage(Constant.MSG_UNKNOWN_REASON);
            return response;
        }
        // 权限检查
        User user = userService.findByUsername(json.getUsername());
        if (user == null || !user.getUsername().equals("admin")) {
            response.setResult(Constant.AUTHENTICATE_FAILURE);
            response.setMessage(Constant.MSG_AUTHENTICATE_FAILURE);
            return response;
        }
        //查询状态处于START的订单
        List<Order> orderList = orderService.getSpecificOrders(Constant.ORDER_STATUS_START);
        List<ResponseOrder> responseOrderList = new ArrayList<ResponseOrder>();
        for(Order order: orderList) {
            ResponseOrder rOrder = new ResponseOrder();
            rOrder.setOrder_id(order.getOrderId());
            rOrder.setTime(order.getTime().toString());
            rOrder.setAddress(order.getAddress());
            rOrder.setFinished(order.getFinished());
            rOrder.setTotal_price(order.getTotalPrice());
            List<Item> items = new ArrayList<Item>();
            //查询该订单的所有产品
            List<OrderProduct> orderProductList = orderProductService.findByOrderId(order.getOrderId());
            for(OrderProduct orderProduct : orderProductList) {
                Product product = productService.findByProductId(orderProduct.getProductId());
                Item item = new Item();
                item.setProduct_price(orderProduct.getPrice());
                item.setProduct_amount(orderProduct.getAmount());
                item.setProduct_name(product.getProductName());
                items.add(item);
            }
            rOrder.setProducts(items);
            responseOrderList.add(rOrder);
        }
        response.setMessage(Constant.MSG_SUCCESS);
        response.setResult(Constant.SUCCESS);
        response.setOrders(responseOrderList);
        return response;
    }
}
